package org.beynet.docs;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.beynet.docs.auth.GSyncCallbackHandler;
import org.beynet.docs.http.DefaultHttpUploaderListener;
import org.beynet.docs.options.CommandLineOptions;
import org.beynet.docs.ui.GSyncMainFrame;
import org.beynet.docs.sync.FileSync;
import org.beynet.docs.sync.FileToSync;

public class GSync {

    public static void main(String[] args) {
        BasicConfigurator.configure();
        CommandLineOptions options = new CommandLineOptions(args, System.out);
        
        String logLevel = options.getLogLevel();
        Logger.getRootLogger().setLevel(Level.ERROR);
        if (CommandLineOptions.LOG_DEBUG.equalsIgnoreCase(logLevel)) {
            Logger.getLogger("org.beynet").setLevel(Level.DEBUG);
        } else if (CommandLineOptions.LOG_INFO.equalsIgnoreCase(logLevel)) {
            Logger.getLogger("org.beynet").setLevel(Level.INFO);
        }
        
        if (options.guid()) {   
            GSyncMainFrame frame = new GSyncMainFrame();
            frame.start();
        } else {
            LoginContext loginCtx = null;
            try {
                loginCtx = new LoginContext("GSync", new GSyncCallbackHandler());
                loginCtx.login();
            } catch (LoginException e) {
                e.printStackTrace();
                System.exit(1);
            }

            ExecutorService executor = new ThreadPoolExecutor(options.getMaxUploadThreads().intValue(),
                    options.getMaxUploadThreads().intValue(), 0,
                    TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
            Date start = new Date();

            if (options.resume()) {
                logger.info("try to resume previous");
                FileSync syncOp = new FileSync(options, executor,new DefaultHttpUploaderListener());
                Subject.doAs(loginCtx.getSubject(), syncOp);
            } else {
                List<FileToSync> files = new ArrayList<FileToSync>();
                for (String source : options.getSource()) {
                    FileToSync f = new FileToSync(new File(source));
                    files.add(f);
                }
                FileSync syncOp = new FileSync(true,files, new DefaultHttpUploaderListener(),options.getDestinationFolder(), options, executor);
                Subject.doAs(loginCtx.getSubject(), syncOp);
            }

            executor.shutdown();
            try {
                do {
                } while (executor.awaitTermination(10, TimeUnit.SECONDS) == false);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Date stop = new Date();
            long res = (stop.getTime() - start.getTime()) / 1000;
            System.out.println("!!!! sync done in " + res + " sec !!!!");
        }

    }
    private final static Logger logger = Logger.getLogger(GSync.class);
}
